﻿#include "dxstdafx.h"
#include "ProvinceData.h"
#include "Data/ScriptData/TerrainID/TerrainIDInfo.h"
#include "Strategy/CStrategyDefine.h"
#include "Strategy/Scene/CStrategyProvinceBorder.h"
#include "Strategy/Scene/CStrategyRenderCommon.h"
#include "Data/DataMgr.h"
#include "ProgramDataMgr.h"
#include "Data/ScriptData/ScriptDataMgr.h"
#include "Data/ScriptData/TerrainID/TerrainIDInfo.h"
#include "Data/ScriptData/TerrainType/TerrainTypeInfo.h"
#include "LandedTitlesData.h"
#include "Data/ScriptData/ProvincePositions/ProvincePositions.h"
#include "Data/ScriptData/LandedTitles/LandedTitles.h"

std::wstring _stProvinceInfo::GetDisplayName() const
{
	if (!DisplayName.empty())
	{
		return DisplayName;
	}
	if (pLandedTitlesData && pLandedTitlesData->m_pLandedTitlesProperty)
	{
		return pLandedTitlesData->GetDisplayName();
	}
	return IndexName;
}

void _stProvinceInfo::InitAreaIn()
{
	for (const auto& it_pProvinceBorder : setProvinceBorder)
	{
		if (it_pProvinceBorder)
		{
			for (const auto& itAreaIn : it_pProvinceBorder->setAreaIn)
			{
				setAreaIn.insert(itAreaIn);
			}
		}		
	}
}

const _stTerrainTypeInfo* _stProvinceInfo::GetTerrainInfo() const
{
	if (nullptr == pst_TerrainPriority)
	{
		return pst_TerrainInfo;
	}
	else
	{
		return pst_TerrainPriority->pTerrainTypeInfo;
	}
}

extern CStrategyProvinceBorder g_StrategyProvinceBorder;
extern CStrategyRenderData g_StrategyRenderData;

void CProvinceData::InseradjacentProvince(_stProvinceInfo* key, _stProvinceInfo* value)
{
	if (nullptr == key || nullptr == value)
	{
		CString strError("nullptr!");
		CommonFunc::ErrorMessageBox(strError);
		return;
	}
	key->setAdjoinProvince.insert(value);
	value->setAdjoinProvince.insert(key);
}

bool CProvinceData::IsDataComplete() const
{
	for (const auto& it : m_mapProvinceInfo)
	{
		if (!it.second.IsAvailable())
		{
			return false;
		}
	}
	return true;
}

bool CProvinceData::CreateProvinceData(const BYTE* pTerrainID, _stRGB*& pProvinceRGB)
{
	// 读取地形图 省份图
	int nTerrainWidth, nTerrainHeight;
	std::wstring szRcPathOut;

	CommonFunc::RelativePath2FullPath(L"\\ResFile\\Scene\\Strategy\\provinces.bmp", szRcPathOut);
	if (!CommonFunc::Read24BitBmp(szRcPathOut, pProvinceRGB, &nTerrainWidth, &nTerrainHeight) || c_nTerrainWidth != nTerrainWidth || c_nTerrainHeight != nTerrainHeight)
	{
		CString strError("Read Province Map Failure!");
		CommonFunc::ErrorMessageBox(strError);
		return false;
	}

	CommonFunc::RelativePath2FullPath(L"\\ResFile\\Scene\\Strategy\\definition.csv", szRcPathOut);
	std::wstring wstrOut = CommonFunc::ReadInputFile(szRcPathOut);
	
	// 读取省份颜色转化配置
	std::unordered_map<_stRGB, _stProvinceInfo*, _stRGBHash> mapProvinceRGB2ID;		// Key 省份颜色 Value 省份指针

	// 解析字符串
	int nFindIndexBegin = 0, nFindIndexEnd = 0;
	while ((nFindIndexEnd = (int)wstrOut.find_first_of(L"\n", nFindIndexBegin)) != std::wstring::npos)
	{
		if (nFindIndexBegin == 0)
		{
			nFindIndexBegin = nFindIndexEnd + 1;
			continue; // 省略第一行
		}
		WORD nProvinceId = 0;
		_stProvinceInfo stProvinceInfo;
		_stRGB stProvinceRGB;
		int nFindIndex1 = nFindIndexBegin, nFindIndex2 = 0;
		for (int i = 0; i < 5; ++i)
		{
			nFindIndex2 = (int)wstrOut.find_first_of(L";", nFindIndex1);
			if (std::string::npos == nFindIndex2)
			{
				CString strError;
				strError.Format(L"%s Format Wrong!", szRcPathOut.c_str());
				CommonFunc::ErrorMessageBox(strError);
				return false;
			}
			switch (i)
			{
			case 0:
				nProvinceId = _wtoi(wstrOut.substr(nFindIndex1, nFindIndex2 - nFindIndex1).c_str());
				break;
			case 1:
				stProvinceRGB.red = _wtoi(wstrOut.substr(nFindIndex1, nFindIndex2 - nFindIndex1).c_str());
				break;
			case 2:
				stProvinceRGB.green = _wtoi(wstrOut.substr(nFindIndex1, nFindIndex2 - nFindIndex1).c_str());
				break;
			case 3:
				stProvinceRGB.blue = _wtoi(wstrOut.substr(nFindIndex1, nFindIndex2 - nFindIndex1).c_str());
				break;
			case 4:
				stProvinceInfo.IndexName = wstrOut.substr(nFindIndex1, nFindIndex2 - nFindIndex1);
				break;
			default:
				break;
			}
			nFindIndex1 = nFindIndex2 + 1;
		}
		if (nProvinceId != 0 && !stProvinceInfo.IndexName.empty())
		{
			stProvinceInfo.nProvinceID = nProvinceId;

			auto iterInsert = m_mapProvinceInfo.insert(std::make_pair(nProvinceId, stProvinceInfo));
			if (!iterInsert.second)
			{
				// 此处可以用insert 因为上面并没有[]
				CString strError;
				strError.Format(L"Province ID repeated %d", nProvinceId);
				CommonFunc::ErrorMessageBox(strError);
				return false;
			}

			if (!mapProvinceRGB2ID.insert(std::make_pair(stProvinceRGB, &iterInsert.first->second)).second)
			{
				CString strError;
				strError.Format(L"Province RGB repeated (%d, %d, %d)", stProvinceRGB.red, stProvinceRGB.green, stProvinceRGB.blue);
				CommonFunc::ErrorMessageBox(strError);
				return false;
			}
		}
		nFindIndexBegin = nFindIndexEnd + 1;
	}

	{
		DWORD dwLength = c_nTerrainWidth * c_nTerrainHeight;
		_stProvinceInfo** temp_pEachPointProvinceInfo = new _stProvinceInfo*[dwLength];
		ZeroMemory(temp_pEachPointProvinceInfo, dwLength * sizeof(_stProvinceInfo*));
		m_pEachPointProvinceInfo.reset(temp_pEachPointProvinceInfo);
	}
	

	// 生成省份地形信息
	for (int iH = 0; iH < c_nTerrainHeight; ++iH)
	{
		for (int jW = 0; jW < c_nTerrainWidth; ++jW)
		{
			DWORD index = CMathFunc::XYTran2Index(jW, iH, c_nTerrainWidth, c_nTerrainHeight);

			auto itFind = mapProvinceRGB2ID.find(pProvinceRGB[index]);
			if (itFind == mapProvinceRGB2ID.end())
			{
				continue;
			}

			m_pEachPointProvinceInfo.get()[index] = itFind->second;
			_stProvinceInfo* pProvinceInfo = itFind->second;
			if (nullptr == pProvinceInfo)
			{
				continue;
			}

			if (0 == pProvinceInfo->nProvinceID)
			{
				CommonFunc::ErrorMessageBox(CString("Province Config Error"));
				continue;
			}

			const _stTerrainIDInfo* cpTerrainProNew = CDataMgr::Singleton().GetScriptDataMgrCPtr()->GetTerrainIDInfoCPtr()->GetInfoCPtr(pTerrainID[index]);
			if (nullptr == cpTerrainProNew)
			{
				continue;
			}

			if (nullptr == pProvinceInfo->pst_TerrainPriority)
			{
				pProvinceInfo->pst_TerrainPriority = cpTerrainProNew;
			}
			else if (pProvinceInfo->pst_TerrainPriority->nPriority < cpTerrainProNew->nPriority)
			{
				pProvinceInfo->pst_TerrainPriority = cpTerrainProNew;
			}
		}
	}
	return true;
}
// 	for (auto& it : m_mapProvinceInfo)
// 	{
// 		if (NULL == it.second.pst_TerrainPriority)
// 		{
// 			continue;	// 排除地图中没有的省份
// 		}
// 		auto itFind = CStrategyScript::Singleton().m_mapTerrainTypeInfo.find(it.second.pst_TerrainPriority->TerrainName);
// 		if (itFind == CStrategyScript::Singleton().m_mapTerrainTypeInfo.end())
// 		{
// 			std::wstring wstrOut;
// 			CommonFunc::StringToWString(it.second.pst_TerrainPriority->TerrainName, wstrOut);
// 			CString strError;
// 			strError.Format(L"Terrain name \"%s\" not find!", wstrOut.c_str());
// 			CommonFunc::ErrorMessageBox(strError);
// 			return false;
// 		}
// 		it.second.pst_TerrainInfo = &itFind->second;
// 
// 		// 		// 只加入陆地省份
// 		// 		if (it.second.pst_TerrainInfo->name != "coastal_desert")
// 		// 		{
// 		// 			std::string lowerProvinceName = it.second.ProvinceName;
// 		// 			transform(it.second.ProvinceName.begin(), it.second.ProvinceName.end(), lowerProvinceName.begin(), ::tolower);
// 		// 			if (!g_StrategyLogicData.m_mapProviceName2ID.insert(std::make_pair(lowerProvinceName, &it.second)).second)
// 		// 			{
// 		// 				assert(0);
// 		// 			}
// 		// 		}
// 	}

bool CProvinceData::TidyProvinceTerrain()
{
	const _stTerrainTypeInfo* cpTerrainTypeOcean = CDataMgr::Singleton().GetScriptDataMgrCPtr()->GetTerrainTypeInfoCPtr()->GetInfoCPtr(L"ocean");
	if (nullptr == cpTerrainTypeOcean)
	{
		CString strError("Terrain ocean cannot find!");
		CommonFunc::ErrorMessageBox(strError);
		return false;
	}

	const _stTerrainTypeInfo* cpTerrainTypeCoastalDesert = CDataMgr::Singleton().GetScriptDataMgrCPtr()->GetTerrainTypeInfoCPtr()->GetInfoCPtr(L"coastal_desert");
	if (nullptr == cpTerrainTypeOcean)
	{
		CString strError("Terrain coastal_desert cannot find!");
		CommonFunc::ErrorMessageBox(strError);
		return false;
	}

	// 将沿海沙漠换成海
	for (auto& itMap : m_mapProvinceInfo)
	{
		if (nullptr == itMap.second.pst_TerrainPriority)
		{
			continue;
		}

		CHECK_CONTINUE(itMap.second.pst_TerrainPriority->pTerrainTypeInfo);

		if (L"coastal_desert" == itMap.second.pst_TerrainPriority->pTerrainTypeInfo->KeyName)
		{
			itMap.second.pst_TerrainPriority = nullptr;
			itMap.second.pst_TerrainInfo = cpTerrainTypeOcean;
		}
	}
	// 将有些沙漠换成沿海沙漠
	for (auto& itMap : m_mapProvinceInfo)
	{
		const _stTerrainTypeInfo* pTerrain = itMap.second.GetTerrainInfo();
		if (nullptr == pTerrain)
		{
			continue;	// 冗余省份
		}
		if (L"desert" == pTerrain->KeyName)
		{
			for (const auto& itSet : itMap.second.setAdjoinProvince)
			{
				CHECK_CONTINUE(itSet);

				const _stTerrainTypeInfo* pTerrainTemp = itSet->GetTerrainInfo();
				CHECK_CONTINUE(pTerrainTemp);

				if (L"ocean" == pTerrainTemp->KeyName)
				{
					itMap.second.pst_TerrainInfo = cpTerrainTypeCoastalDesert;
					break;
				}
			}
		}
	}
	// 仍然需要转换 如Kent的地形还是ocean
	return true;
}

void CProvinceData::LinkLandedTitleNProvinceData()
{
	for (auto& itMap : m_mapProvinceInfo)
	{
// 		const _stTerrainTypeInfo* cpTerrainTypeOcean = CDataMgr::Singleton().GetScriptDataMgrCPtr()->GetTerrainTypeInfoCPtr()->GetInfoCPtr(L"ocean");
// 		if (cpTerrainTypeOcean != itMap.second.GetTerrainInfo())
// 		{
			CLandedTitlesData* pCLTD = const_cast<CLandedTitlesData*>(CDataMgr::Singleton().GetProgramDataMgrCPtr()->GetCLandedTitlesDataCPtr());
			pCLTD->LinkWithProvinceData(&itMap.second);
//		}
	}
}

void CProvinceData::LinkPositions2ProvinceData()
{
	for (auto& itMap : m_mapProvinceInfo)
	{
		const CProvincePosition* p = CDataMgr::Singleton().GetScriptDataMgrCPtr()->GetProvincePositionCPtr();
		if (p)
		{
			itMap.second.pProvincePosition = p->GetProvincePosition(itMap.second.nProvinceID);
		}
	}
}

void CProvinceData::InitAreaIn()
{
	for (auto& itMap : m_mapProvinceInfo)
	{
		itMap.second.InitAreaIn();
	}
}
